package sourceFiles;

import java.util.LinkedList;
import java.util.Map;

import Exceptions.InvalidChildID;
import Exceptions.InvalidGuardianID;
import Exceptions.InvalidRideId;
import Exceptions.TicketDoesntExist;
import Exceptions.CentralComputerExceptions.ChildIDDoesntExist;
import Exceptions.CentralComputerExceptions.ErrorInGuardianPassword;
import Exceptions.CentralComputerExceptions.GuardianIDDoesntExist;
import Exceptions.CentralComputerExceptions.InvalidPassword;
import Exceptions.CentralComputerExceptions.NoChildrenForGuardian;
import Exceptions.CentralComputerExceptions.RideIDDoesntExist;
import sourceFiles.IApplication;
import sourceFiles.ICentralComputer;

/**
* A class that responsible for all application functionality in E-Park. 
* The user that uses the application, can login and purchase rides tickets his children.
* The user can cancel previous acquisitions.
* The user can supervise his children by display in the application the children positions
* in E-Park rides.
* @author LASO-Team
* 
*/

public class Application implements IApplication {

	private Integer guardianID;
	private Integer currentChildID;
	private ICentralComputer centralComputer;

	/*--------------------------------------------------------------------------*/
	/**
	 * Application c'tor
	 * @param centralComp
	 * 			the central computer to connect with
	 */
	public Application(ICentralComputer centralComp) {
		if (centralComp == null) {
			throw new NullPointerException();
		}
		guardianID = null;
		currentChildID = null;
		centralComputer = centralComp;
	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#login(java.lang.Integer, java.lang.String)
	 */
	@Override
	public void login(Integer userID, String userPassword)
			throws InvalidGuardianID, InvalidPassword, GuardianIDDoesntExist,
			ErrorInGuardianPassword {

		// checks the userID and the password with the central computer
		centralComputer.connectGuardian(userID, userPassword);
		// if no exception has been thrown, updates the current user in the
		// application
		guardianID = userID;

	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#logout()
	 */
	@Override
	public void logout() {
		// reset the guardianID to null since no user is connected
		guardianID = null;

	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#displayChildrenPosition(java.lang.Integer)
	 */
	@Override
	public Map<Integer, Integer> displayChildrenPosition(Integer guardianID)
			throws GuardianIDDoesntExist, NoChildrenForGuardian, InvalidGuardianID {

		// return the guardian's children locations
		return centralComputer.retrieveChildrenLocation(guardianID);

	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#displayChildETicket(java.lang.Integer)
	 */
	@Override
	public ETicket displayChildETicket(Integer childID)
			throws ChildIDDoesntExist, InvalidChildID {

		// return the child E-Ticket
		return centralComputer.retrieveChildETicket(childID);

	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#displayRidesCatalog()
	 */
	@Override
	public LinkedList<RideEntry> displayRidesCatalog() {

		// return the rides catalog
		return centralComputer.getRidesCatalog();

	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#buyTicket(java.lang.Integer, java.lang.Integer, java.lang.Integer)
	 */
	@Override
	public void buyTicket(Integer rideID, Integer guardianID, Integer childID)
			throws InvalidRideId, ChildIDDoesntExist, RideIDDoesntExist,
			GuardianIDDoesntExist, InvalidChildID, InvalidGuardianID {

		// calls the buyingProcess function to buy new ticket. if an error
		// occurred it will throw the correct exception
		centralComputer.buyingProcess(rideID, guardianID, childID);

	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#cancelTicket(java.lang.Integer, java.lang.Integer, java.lang.Integer)
	 */
	@Override
	public void cancelTicket(Integer rideID, Integer guardianID, Integer childID)
			throws InvalidRideId, ChildIDDoesntExist, RideIDDoesntExist,
			TicketDoesntExist, GuardianIDDoesntExist, InvalidGuardianID,
			InvalidChildID {

		// calls the cancelAcquisition function to cancel the acquisition. if an
		// error occurred it will throw the correct exception
		centralComputer.cancelAcquisition(rideID, guardianID, childID);

	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#getGuardianID()
	 */
	public Integer getGuardianID() {
		return guardianID;
	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#setGuardianID(java.lang.Integer)
	 */
	public void setGuardianID(Integer guardianID) {
		this.guardianID = guardianID;
	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#getCurrentChildID()
	 */
	public Integer getCurrentChildID() {
		return currentChildID;
	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#setCurrentChildID(java.lang.Integer)
	 */
	public void setCurrentChildID(Integer currentChildID) {
		this.currentChildID = currentChildID;
	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#getCentralComputer()
	 */
	public ICentralComputer getCentralComputer() {
		return centralComputer;
	}

	/* (non-Javadoc)
	 * @see sourceFiles.IApplication#setCentralComputer(sourceFiles.ICentralComputer)
	 */
	public void setCentralComputer(ICentralComputer centralComputer) {
		this.centralComputer = centralComputer;
	}

	// @Override
	// public void applicationCycle() {

	// }

}
